package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicProductionDispatchDAO;
import com.cssy.xxkj.logic.dao.LogicProductionDispatchItemDAO;
import com.cssy.xxkj.logic.dao.LogicProductionDispatchingItemDAO;
import com.cssy.xxkj.logic.dao.LogicProductionPlanDAO;
import com.cssy.xxkj.logic.dao.LogicProductionPlanItemDAO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchDO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchItemDO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchingDO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchingItemDO;
import com.cssy.xxkj.logic.entity.LogicProductionPlanDO;
import com.cssy.xxkj.logic.entity.LogicProductionPlanItemDO;
import com.cssy.xxkj.logic.service.ILogicProductionDispatchService;
import com.cssy.xxkj.logic.service.ILogicProductionDispatchingService;
import com.cssy.yd.logic.util.MathUtil;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;
/**
 * 生产调度业务方法
 * @modify hf 
 *
 */
@Service("logicProductionDispatchService")
public class LogicProductionDispatchServiceImpl implements ILogicProductionDispatchService {
	private static final Logger logger = Logger.getLogger(LogicProductionDispatchServiceImpl.class);
	@Resource(name = "logicProductionDispatchDAO")
	private LogicProductionDispatchDAO logicProductionDispatchDAO;
	//生产计划Service
	@Resource(name = "logicProductionPlanDAO")
	private LogicProductionPlanDAO logicProductionPlanDAO;
	
	//生产计划Service
	@Resource(name = "logicProductionPlanItemDAO")
	private LogicProductionPlanItemDAO logicProductionPlanItemDAO;
	
	@Resource(name = "logicProductionDispatchItemDAO")
	private LogicProductionDispatchItemDAO  logicProductionDispatchItemDAO;
	
	@Resource(name = "logicProductionDispatchingService")
	private ILogicProductionDispatchingService  logicProductionDispatchingService;
	
	@Resource(name = "logicProductionDispatchingItemDAO")
	private LogicProductionDispatchingItemDAO logicProductionDispatchingItemDAO;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicProductionDispatchDO>  list=logicProductionDispatchDAO.find(scs);
		rs.setRecordCount(logicProductionDispatchDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		logicProductionDispatchDAO.deleteLogicProductionDispatchDOByPrimaryKey(id);
		return null;
	}

	@Override
	public Integer update(LogicProductionDispatchDO t, User user) throws SyBaseException {
		t.setBizModifyName(user.getName());
		t.setBizModifyDate(new Date());
		t.setBizVersionMark(t.getBizVersion());
		t.setBizVersion(t.getBizVersion()+1);
		return logicProductionDispatchDAO.updateLogicProductionDispatchDO(t);
	}

	@Override
	public LogicProductionDispatchDO save(LogicProductionDispatchDO sodo, User user) throws SyBaseException {
		sodo.setBizCreatorName(user.getName());
		sodo.setBizCreatorDate(new Date());
		sodo.setBizVersion(1);
		logicProductionDispatchDAO.insertLogicProductionDispatchDO(sodo);
		return sodo;
	}

	@Override
	public LogicProductionDispatchDO findListById(String id) throws SyBaseException {
		return logicProductionDispatchDAO.findLogicProductionDispatchDOByPrimaryKey(id);
	}


	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicProductionDispatchDAO.deleteBizRemoved(id);
	}

	

	@Override
	public List<LogicProductionDispatchItemDO> findDispatItemList(String id) throws SyBaseException {
		SearchConditions scs = new SearchConditions();
		scs.setRemovedProperty(null);
		scs.addCondition("zd001ProDispatId", id, SearchCondition.OP_EQUAL);
		List<LogicProductionDispatchItemDO>  list=logicProductionDispatchItemDAO.find(scs);
		return list;
	}
	
	@Override
	public List<LogicProductionDispatchItemDO> findItemListByExample(SearchConditions scs)throws SyBaseException{
		if(scs.getOrderBy()==null||scs.getOrderBy().equals("")){
			scs.setOrderBy("(zd031Order+0)");
		}
		List<LogicProductionDispatchItemDO>  list=logicProductionDispatchItemDAO.find(scs);
		return list;
	}
	
	@Override
	public void dispatSave(HttpServletRequest request, LogicProductionDispatchDO curAP)
			throws SyBaseException {
		try {
			String itemdata = request.getParameter("itemdata");//物品数据
			String paramflag =request.getParameter("paramflag");
			String orderDate = request.getParameter("zd005OrderDate");
			if(StringUtils.isNotBlank(orderDate)){
				curAP.setZd005OrderDate(DateUtils.stringToDate(orderDate));
			}
			String deliveryDate = request.getParameter("zd006DeliveryDate");
			if(StringUtils.isNotBlank(deliveryDate)){
				curAP.setZd006DeliveryDate(DateUtils.stringToDate(deliveryDate));
			}
			curAP.setZd008Billstatus(paramflag);//单据状态
			List<LogicProductionDispatchItemDO> Itemlist = JSONArray.parseArray(itemdata,LogicProductionDispatchItemDO.class);
			User user = SessionUtil.getUser(request);
			if (StringUtils.isBlank(curAP.getId())) {
					String id = IDCodeTypeUtil.getId();
					curAP.setId(id);
					curAP.setZd001FormCode(syCodeService.getCode(BillTypeConstant.PRODISPATCH,BillTypeConstant.PRODISPATCH,SyCode.DATE_YYMM,5));
					this.save(curAP,user);
					for (LogicProductionDispatchItemDO ItemDO : Itemlist) {
						ItemDO.setZd001ProDispatId(id);
						ItemDO.setId(IDCodeTypeUtil.getId());
						logicProductionDispatchItemDAO.insertLogicProductionDispatchItemDO(ItemDO);
					}
					logger.info("新增生产调度单成功");
			} else {
					int rs=this.update(curAP, user);
					if(0==rs){
						throw new SyBaseException("您操作的单据数据发生了改变!请您重新打开编辑！");
					}
					if(Itemlist!=null&&!Itemlist.isEmpty()&&Itemlist.size()>0){
						logicProductionDispatchItemDAO.deleteDispatId(curAP.getId());
						List<LogicProductionDispatchItemDO> list = this.findByIdItem(curAP,true);
						for(int i=0;i<Itemlist.size();i++){
							if(this.validateSubmit(list, Itemlist.get(i))){
								throw new SyBaseException("订单工序调度总数量大于订单数量，不合法！");
							}
							Itemlist.get(i).setZd001ProDispatId(curAP.getId());
							Itemlist.get(i).setId(IDCodeTypeUtil.getId());
							logicProductionDispatchItemDAO.insertLogicProductionDispatchItemDO(Itemlist.get(i));
						}
					}
					logger.info("修改生产调度单成功");
			}
			if(curAP.getZd008Billstatus().equals(BillStatusUtil.PRODISPATCH_BILL_STATUS_TWO)){
				LogicProductionPlanDO plan = new LogicProductionPlanDO();
				plan.setZd001FormCode(curAP.getZd002OriCode());
				List<LogicProductionPlanDO> planlist=logicProductionPlanDAO.findListByExample(plan);
				if(planlist!=null&&!planlist.isEmpty()&&planlist.size()>0){
					if(this.validateReturn(this.findByIdItem(curAP,false), planlist.get(0).getId())){
						planlist.get(0).setZd008Billstatus(BillStatusUtil.PROPLAN_BILL_STATUS_FOUR);
					}else{
						planlist.get(0).setZd008Billstatus(BillStatusUtil.PROPLAN_BILL_STATUS_THREE);
					}
					planlist.get(0).setBizVersionMark(planlist.get(0).getBizVersion());
					planlist.get(0).setBizVersion(planlist.get(0).getBizVersion()+1);
					int r=logicProductionPlanDAO.updateLogicProductionPlanDO(planlist.get(0));
					if(0==r){
						throw new SyBaseException("您操作的原始单据数据发生了改变!请您重新打开编辑！");
					}
					logger.info("更新生产计划单状态成功");
				}
				
				//生成生产派工单
				Map<String, List<LogicProductionDispatchItemDO>> disItemMap = this.combDispachItemMapToMap(Itemlist);
				for(String keyStr : disItemMap.keySet()){
					List<LogicProductionDispatchItemDO> _dispItemList = disItemMap.get(keyStr);
					this.processToDispathing(curAP, keyStr, _dispItemList, user);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error("操作生产调度单失败！");
			throw new SyBaseException(GlobalResLoader.getOpfailed()
					+ e.getMessage());
		}
	}
	
	/**
	 * 按车间区分工序
	 * @param dispachItemList
	 * @return
	 */
	private Map<String, List<LogicProductionDispatchItemDO>> combDispachItemMapToMap(List<LogicProductionDispatchItemDO> dispachItemList){
		Map<String, List<LogicProductionDispatchItemDO>> dispatchItemMap = new HashMap<String, List<LogicProductionDispatchItemDO>>();
		for(LogicProductionDispatchItemDO disItem : dispachItemList){
			if(disItem==null||StringUtils.isBlank(disItem.getId())){
				continue;
			}
			String keyStr = disItem.getZd028WorkShop();
			List<LogicProductionDispatchItemDO> dispItemList = dispatchItemMap.get(keyStr);
			if(dispItemList==null){
				dispItemList = new ArrayList<LogicProductionDispatchItemDO>();
				dispatchItemMap.put(keyStr, dispItemList);
			}
			dispItemList.add(disItem);
		}
		return dispatchItemMap; 
	}
	
	private void processToDispathing(LogicProductionDispatchDO dispach, String workShopCode,
			List<LogicProductionDispatchItemDO> dispatchItemList, User user)
			throws SyBaseException {
		try{
			LogicProductionDispatchingDO gdispatching = new LogicProductionDispatchingDO();
			String parimaryId = IDCodeTypeUtil.getId();
			String zdFormCode = syCodeService.getCode(BillTypeConstant.PRODISPAT,BillTypeConstant.PRODISPAT,SyCode.DATE_YYMM,5);
			gdispatching.setId(parimaryId);
			gdispatching.setZd001FormCode(zdFormCode);
			gdispatching.setZd002SaleId(dispach.getZd002SaleId());
			gdispatching.setZd002OriCode(dispach.getZd001FormCode());
			gdispatching.setZd003PiCode(dispach.getZd003PiCode());
			gdispatching.setZd004CustomerId(dispach.getZd004CustomerId());
			gdispatching.setZd004CustomerCode(dispach.getZd004CustomerCode());
			gdispatching.setZd004CustomerName(dispach.getZd004CustomerName());
			gdispatching.setZd005OrderDate(dispach.getZd005OrderDate());
			gdispatching.setZd006DeliveryDate(dispach.getZd006DeliveryDate());
			gdispatching.setZd007SalesMan(dispach.getZd007SalesMan());
			gdispatching.setZd008Billstatus(BillStatusUtil.PRODISPAT_BILL_STATUS_ZERO);
			gdispatching.setZd009Remark(dispach.getZd009Remark());
			gdispatching.setZd011WorkShopCode(workShopCode);
			
			logicProductionDispatchingService.save(gdispatching, user);
			
			for(LogicProductionDispatchItemDO dispatchItem : dispatchItemList){
				if(dispatchItem==null){
					continue;
				}
				LogicProductionDispatchingItemDO gdispatchingItem = new LogicProductionDispatchingItemDO();
				gdispatchingItem.setId(IDCodeTypeUtil.getId());
				gdispatchingItem.setZd001ProDispatId(parimaryId);
				gdispatchingItem.setZd002ProDispatCode(zdFormCode);
				gdispatchingItem.setZd003CustomerId(dispatchItem.getZd003CustomerId());
				gdispatchingItem.setZd004CustomerCode(dispatchItem.getZd004CustomerCode());
				gdispatchingItem.setZd005CustomerName(dispatchItem.getZd005CustomerName());
				gdispatchingItem.setZd006MaterialsId(dispatchItem.getZd006MaterialsId());
				gdispatchingItem.setZd006MaterialsCode(dispatchItem.getZd006MaterialsCode());
				gdispatchingItem.setZd006MaterialsName(dispatchItem.getZd006MaterialsName());
				gdispatchingItem.setZd009MaterialsBatch(dispatchItem.getZd009MaterialsBatch());
				gdispatchingItem.setZd010MaterialsModel(dispatchItem.getZd010MaterialsModel());
				gdispatchingItem.setZd011MaterialsSpec(dispatchItem.getZd011MaterialsSpec());
				gdispatchingItem.setZd012MaterialsUnit(dispatchItem.getZd012MaterialsUnit());
				gdispatchingItem.setZd013Price(dispatchItem.getZd014Price());
				//订单数量
				gdispatchingItem.setZd015PlanQuantity(dispatchItem.getZd030PlanQuantity());
				gdispatchingItem.setZd021MaterialsDescription(dispatchItem.getZd021MaterialsDescription());
				gdispatchingItem.setZd022OpenBatch(dispatchItem.getZd022OpenBatch());
				gdispatchingItem.setZd023MaterialsSize(dispatchItem.getZd023MaterialsSize());
				gdispatchingItem.setZd024MaterialsPicture(dispatchItem.getZd024MaterialsPicture());
				gdispatchingItem.setZd025MaterialsAnnex(dispatchItem.getZd025MaterialsAnnex());
				gdispatchingItem.setZd026MaterialsColor(dispatchItem.getZd026MaterialsColor());
				gdispatchingItem.setZd027MaterialsQuality(dispatchItem.getZd027MaterialsQuality());
				gdispatchingItem.setZd028WorkShop(dispatchItem.getZd028WorkShop());
				gdispatchingItem.setZd028WorkShopName(dispatchItem.getZd028WorkShopName());
				gdispatchingItem.setZd029Process(dispatchItem.getZd029Process());
				gdispatchingItem.setZd029ProcessName(dispatchItem.getZd029ProcessName());
				gdispatchingItem.setZd029Order(dispatchItem.getZd031Order());
				logicProductionDispatchingItemDAO.insertLogicProductionDispatchingItemDO(gdispatchingItem);
			}
		}catch(Exception e){
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed() + e.getMessage());
		}
	}
	
	/**
	 * 验证调度数量是否合法
	 * @param list
	 * @param ItemDO
	 * @return
	 */
	private boolean validateSubmit(List<LogicProductionDispatchItemDO> list,LogicProductionDispatchItemDO ItemDO){
		BigDecimal bg = MathUtil.mathUtil.subtract(ItemDO.getZd030PlanQuantity(),ItemDO.getZd013Quantity());
		boolean bl =false;//默认验证 
		if(list!=null&&!list.isEmpty()&&list.size()>0){
			for(int i=0;i<list.size();i++){
				if(ItemDO.getZd029Process().equals(list.get(i).getZd029Process())){
					bg=MathUtil.mathUtil.subtract(bg, list.get(i).getZd013Quantity());
				}
			}
			if(bg.compareTo(new BigDecimal(0))==-1){
				bl= true;
			}
		}
		return bl;
	}
	
	private List<LogicProductionDispatchItemDO> findByIdItem(LogicProductionDispatchDO curAP,boolean bl){
		List<LogicProductionDispatchItemDO> list = new ArrayList<LogicProductionDispatchItemDO>();
		SearchConditions scs = new SearchConditions();
		scs.setRemovedProperty("removed");
		if(bl){
			scs.addCondition("zd001FormCode", curAP.getZd001FormCode(), SearchCondition.OP_NOTEQUAL);
		}
		scs.addCondition("zd002OriCode", curAP.getZd002OriCode(), SearchCondition.OP_EQUAL);
		scs.addCondition("zd008Billstatus", BillStatusUtil.PRODISPATCH_BILL_STATUS_ONEW, SearchCondition.OP_NOTEQUAL);
		List<LogicProductionDispatchDO> result = this.findListByExample(scs).getResults();
		if(result!=null&&!result.isEmpty()&&result.size()>0){
			for(int i=0;i<result.size();i++){
				List<LogicProductionDispatchItemDO> dispatItem = this.findDispatItemList(result.get(i).getId());
				list.addAll(dispatItem);
			}
		}
		return list;
	}
	
	/**
	 * 验证是否已经全部调度完成
	 * @param list
	 * @param planId
	 * @return
	 */
	private boolean validateReturn(List<LogicProductionDispatchItemDO> list,String getId){
		LogicProductionPlanItemDO getitem = new LogicProductionPlanItemDO();
		getitem.setZd001ProPlanId(getId);
		List<LogicProductionPlanItemDO> getitemlist=logicProductionPlanItemDAO.findListByExample(getitem);
		boolean bl =true;//是否全部 完成
		for(int n=0;n<getitemlist.size();n++){
			BigDecimal bd=getitemlist.get(n).getZd013Quantity();
			for(int i=0;i<list.size();i++){
				bd=MathUtil.mathUtil.subtract(bd, list.get(i).getZd013Quantity());
				for(int k=0;k<list.size();k++){
					if(!list.get(i).getId().equals(list.get(k).getId())&&list.get(i).getZd029Process().equals(list.get(k).getZd029Process())){
						bd=MathUtil.mathUtil.subtract(bd, list.get(k).getZd013Quantity());	
					}
				}
			}
			if(bd.compareTo(new BigDecimal(0))==1){
				bl=false;
			}
		}
		return bl;
	}
	
	@Override
	public void deleteBizRemovedBySaleId(String backSaleId)throws SyBaseException{
		SearchConditions patchScs = new SearchConditions();
		patchScs.addCondition("zd002SaleId", backSaleId, SearchCondition.OP_EQUAL);
		List<LogicProductionDispatchDO> patchList = logicProductionDispatchDAO.find(patchScs);
		if(patchList==null||patchList.isEmpty()||patchList.size()==0){
			return;
		}else{
			for(LogicProductionDispatchDO patch : patchList){
				if(patch==null||StringUtils.isBlank(patch.getId())){
					continue;
				}
				logicProductionDispatchDAO.deleteBizRemoved(patch.getId());
			}
		}
	}
}
